#pragma once

#include "localcommon.hpp"
#include <sys/epoll.h>

namespace Local_Epoller
{
    class LocalEpoller
    {
    public:
        /**********构造析构************** */
        LocalEpoller() : _epfd(-1)

        {
            _epfd = epoll_create(128);
            if (_epfd < 0)
            {
                Local_Log::LOG(Local_Log::LogLever::LFATAL) << "epoll_create error";
                exit(ExitCord::ERR_EPOLL_CREATE);
            }
            Local_Log::LOG(Local_Log::LogLever::LINFO) << "epoll_create success " << _epfd;
        }
        ~LocalEpoller()
        {
            if (_epfd >= 0)
            {
                close(_epfd);
            }
        }

        /**********virtual************** */
        /**********成员函数************** */
        void AddEvent(int sockfd, uint32_t events)
        {
            struct epoll_event lo_ev;
            lo_ev.events = events;
            lo_ev.data.fd = sockfd;

            int ret_ctl = epoll_ctl(_epfd, EPOLL_CTL_ADD, sockfd, &lo_ev);
            if (ret_ctl < 0)
            {
                Local_Log::LOG(Local_Log::LogLever::LFATAL) << "AddEvent error";
                exit(ExitCord::ERR_EPOLL_CTL);
            }
            Local_Log::LOG(Local_Log::LogLever::LINFO) << "AddEvent success " << _epfd;
        }
        void DelEvent(int sockfd)
        {
            int ret_ctl = epoll_ctl(_epfd, EPOLL_CTL_DEL, sockfd, nullptr);
            if (ret_ctl < 0)
            {
                Local_Log::LOG(Local_Log::LogLever::LFATAL) << "DelEvent error";
                exit(ExitCord::ERR_EPOLL_CTL);
            }
            Local_Log::LOG(Local_Log::LogLever::LINFO) << "DelEvent success " << _epfd;
        }
        void ModEvent(int sockfd, uint32_t events)
        {
            struct epoll_event lo_ev;
            lo_ev.events = events;
            lo_ev.data.fd = sockfd;

            int ret_ctl = epoll_ctl(_epfd, EPOLL_CTL_MOD, sockfd, &lo_ev);
            if (ret_ctl < 0)
            {
                Local_Log::LOG(Local_Log::LogLever::LFATAL) << "ModEvent error";
                exit(ExitCord::ERR_EPOLL_CTL);
            }
            Local_Log::LOG(Local_Log::LogLever::LINFO) << "ModEvent success " << _epfd;
        }
        int WaitEvent(struct epoll_event *event, const int maxevent, const int timeout)
        {
            int ret_wai = epoll_wait(_epfd, event, maxevent, timeout);
            if (ret_wai < 0)
            {
                Local_Log::LOG(Local_Log::LogLever::LERROR) << "WaitEvent error ";
            }
            else if (ret_wai == 0)
            {
                Local_Log::LOG(Local_Log::LogLever::LERROR) << "WaitEvent timeout ";
            }
            else
            {
                Local_Log::LOG(Local_Log::LogLever::LERROR) << "WaitEvent success ";
            }
            return ret_wai;
        }
        /**********GetSet************** */
    private:
        int _epfd;
    };
}